#ifndef _SOC_H_
#define _SOC_H_

#include "mdev.h"

/************* CPU Type *************/
#define SOC_CORTEX_M4

/************* Memory Address Map *************/
//#define SOC_ROM_START                  0x00010000  /* 32KB */
//#define SOC_ROM_END                    0x00007FFF
#define SOC_FLASH_START                0x08000000  /* 1MB */
#define SOC_FLASH_END                  0x080FFFFF
//#define SOC_INFO_START                 0x10020000  /* 2KB */
//#define SOC_INFO_END                   0x100207FF
#define SOC_SRAM1_START                0x20000000  /* 112KB */
#define SOC_SRAM1_END                  0x2001BFFF

#define SOC_SRAM2_START                0x2001C000  /* 16KB，SRAM1和SRAM2的访
                                                      问可同时进行 */
#define SOC_SRAM2_END                  0x2001FFFF
#define SOC_SRAM2_SIZE                 0x00004000  /* 16KB */

#define SOC_CCM_START                  0x10000000  /* 64KB */
#define SOC_CCM_END                    0x1000FFFF
#define SOC_FSMC_SRAM_STAR             0x68000000
#define SOC_FSMC_SRAM_END              0x680FFFFF
#define SOC_FSMC_SRAM_SIZE             0x00100000  /* 1MB */
//#define SOC_FLASH_SECTOR_SIZE          0x400       /* 1KB */
//#define SOC_INFO_SECTOR_SIZE           0x100       /* 256B */
//#define SOC_FLASH_CHIP_SIZE            0x20000     /* 128KB */

/**
 * 用于位带操作的外设基地址
 */
/* Memory */
#define SOC_BASE_SRAM                  0x20000000U
/* Peripheral */
/* APB1 */
#define SOC_BASE_TIM2                  0x40000000U
#define SOC_BASE_TIM3                  0x40000400U
#define SOC_BASE_TIM4                  0x40000800U
#define SOC_BASE_TIM5                  0x40000C00U
#define SOC_BASE_TIM6                  0x40001000U
#define SOC_BASE_TIM7                  0x40001400U
#define SOC_BASE_TIM12                 0x40001800U
#define SOC_BASE_TIM13                 0x40001C00U
#define SOC_BASE_TIM14                 0x40002000U
#define SOC_BASE_RTC_BKP               0x40002800U
#define SOC_BASE_WWDG                  0x40002800U
#define SOC_BASE_IWDG                  0x40003000U
#define SOC_BASE_I2S2_EXT              0x40003400U
#define SOC_BASE_SPI2_I2S2             0x40003800U
#define SOC_BASE_SPI3_I2S3             0x40003C00U
#define SOC_BASE_I2S3_EXT              0x40004000U
#define SOC_BASE_USART2                0x40004400U
#define SOC_BASE_USART3                0x40004800U
#define SOC_BASE_UART4                 0x40004C00U
#define SOC_BASE_UART5                 0x40005000U
#define SOC_BASE_I2C1                  0x40005400U
#define SOC_BASE_I2C2                  0x40005800U
#define SOC_BASE_I2C3                  0x40005C00U
#define SOC_BASE_CAN1                  0x40006400U
#define SOC_BASE_CAN2                  0x40006800U
#define SOC_BASE_PWR                   0x40007000U
#define SOC_BASE_DAC                   0x40007400U
#define SOC_BASE_UART7                 0x40007800U
#define SOC_BASE_UART8                 0x40007C00U
/* APB2 */
#define SOC_BASE_TIM1                  0x40010000U
#define SOC_BASE_TIM8                  0x40010400U
#define SOC_BASE_USART1                0x40011000U
#define SOC_BASE_USART6                0x40011400U
#define SOC_BASE_ADC1_ADC2_ADC3        0x40012000U
#define SOC_BASE_SDIO                  0x40012C00U
#define SOC_BASE_SPI1                  0x40013000U
#define SOC_BASE_SPI4                  0x40013400U
#define SOC_BASE_SYSCFG                0x40013800U
#define SOC_BASE_EXTI                  0x40013C00U
#define SOC_BASE_TIM9                  0x40014000U
#define SOC_BASE_TIM10                 0x40014400U
#define SOC_BASE_TIM11                 0x40014800U
#define SOC_BASE_SPI5                  0x40015000U
#define SOC_BASE_SPI6                  0x40015400U
/* AHB1 */
#define SOC_BASE_GPIOA                 0x40020000U
#define SOC_BASE_GPIOB                 0x40020400U
#define SOC_BASE_GPIOC                 0x40020800U
#define SOC_BASE_GPIOD                 0x40020C00U
#define SOC_BASE_GPIOE                 0x40021000U
#define SOC_BASE_GPIOF                 0x40021400U
#define SOC_BASE_GPIOG                 0x40021800U
#define SOC_BASE_GPIOH                 0x40021C00U
#define SOC_BASE_GPIOI                 0x40022000U
#define SOC_BASE_CRC                   0x40023000U
#define SOC_BASE_RCC                   0x40023800U
#define SOC_BASE_NVMC                  0x40023C00U
#define SOC_BASE_BKPSRAM               0x40024000U
#define SOC_BASE_DMA1                  0x40026000U
#define SOC_BASE_DMA2                  0x40026400U
#define SOC_BASE_MAC                   0x40028000U
#define SOC_BASE_USB_OTG_HS            0x40040000U

/**
 * GPIO位带操作
 */
#define SOC_OFF_GPIO_IDR               0x10U
#define SOC_OFF_GPIO_ODR               0x14U
#define SOC_BIT_GPIO_PIN_0_15D(val)    (val)
#define SOC_VAL_GPIO_ODR_LOW           0x0
#define SOC_VAL_GPIO_ODR_HIGH          0x1

/**
 * 外部中断位带操作
 */
#define SOC_OFF_EXTI_IMR               0x00U
#define SOC_BIT_EXTI_IMR_0_22D(val)    (val)
#define SOC_VAL_EXTI_IMR_FORBID        0x0
#define SOC_VAL_EXTI_IMR_PERMIT        0x1

/**
 * 定时器位带操作
 */
#define SOC_OFF_TIM_CR1                0x00U
#define SOC_BIT_TIM_CR1_EN             0x00U
#define SOC_VAL_TIM_CR1_STOP           0x0
#define SOC_VAL_TIM_CR1_RUN            0x1

/**
 * USART位带操作
 */
#define SOC_OFF_USART_CR1              0x0CU
#define SOC_BIT_USART_CR1_RXNEIE       0x5
#define SOC_VAL_USART_CR1_RXNEIE_DIS   0x0
#define SOC_VAL_USART_CR1_RXNEIE_EN    0x1
#define SOC_BIT_USART_CR1_IDLEIE       0x4
#define SOC_BIT_USART_CR1_IDLEIE_DIS   0x0
#define SOC_BIT_USART_CR1_IDLEIE_EN    0x1
#define SOC_OFF_USART_CR3              0x14U
#define SOC_BIT_USART_CR3_DMAR         0x6
#define SOC_VAL_USART_CR3_DMAR_DIS     0x0
#define SOC_VAL_USART_CR3_DMAR_EN      0x1
#define SOC_BIT_USART_CR3_DMAT         0x7
#define SOC_VAL_USART_CR3_DMAT_DIS     0x0
#define SOC_VAL_USART_CR3_DMAT_EN      0x1
#define SOC_OFF_USART_SR               0x00U
#define SOC_BIT_USART_SR_TC            0x6
#define SOC_VAL_USART_SR_TC_CLEAR      0x0
#define SOC_VAL_USART_SR_TC_SET        0x1

/**
 * ARM位带操作：
 *   0x20000000-0x200FFFFF映射到0x22000000-0x23FFFFFF
 *   0x40000000-0x400FFFFF映射到0x42000000-0x43FFFFFF
 */
#define SOC_BITBAND(addr, bit)         (*(_RW *)(((addr) & 0xF0000000) | \
                    0x02000000 | (((addr) & 0x000FFFFF) * 32 + (bit) * 4)))

/**
 * 用于位带操作的宏
 */
#define SOC_BITBAND_READ(base, off, bit)        SOC_BITBAND(base+off, bit)
#define SOC_BITBAND_WRITE(base, off, bit, val)  SOC_BITBAND(base+off, \
                                                bit) = val

#endif /* _SOC_H_ */
